
/* 列表的 类型
import type {
  IGridMeta,
  IGridTable,
  IGridItem,
  IGridSelection
} from '../../types/50-grid'
*/

// 拖拽的 类型
import type {
  IDragInfo,
  IDragEvent
} from '../../types/70-drag'

/**
 * 把 dom 变成可以拖拽的形式，记录拖拽信息。
 * * 针对table的th，form 和 find 的div
 */
export default class domDrag {
  dom: any
  align: () => void
  order: () => void
  removeDom: () => void
  modCol: (colId: string | number, event) => void

  /**
   * 传入一个 dom，设置拖拽属性，触发拖拽事件
   * @param _dom 要拖拽的dom，比如 table 的th，表单的div等
   * @param colOrder 排序的字段ID  Array<number|string>
   * @param dragInfo 拖拽信息 IDragInfo
   * @param colId 字段ID string | number
   * @param dragEvent 拖拽触发的事件 IDragEvent
   */
  constructor (
    _dom: HTMLTableCellElement | HTMLDivElement | any, //需要拖拽的dom
    colOrder: Array<number|string>, //用于字段的排序
    dragInfo: IDragInfo, //拖拽信息
    colId: string, //字段ID
    dragEvent: any //拖拽的处理事件
  ) {
    this.dom = _dom
    this.align = dragEvent.setAlign  // 设置对齐（grid专用）
    this.order = dragEvent.setOrder // 设置排序（共用）
    this.removeDom = dragEvent.removeDom // 移除 dom
    this.modCol = dragEvent.modCol // 移除 dom

    // 设置单击事件，打开修改字段属性的事件
    this.dom.onclick = (event: any) => {
      // console.log('拖拽里的单击：', event)
      // console.log('拖拽里的 dragInfo：', colId, dragInfo)
      if (event.ctrlKey) {
        // console.log('拖拽里的 meta：')
        if (typeof this.modCol === 'function') {
          this.modCol(colId, event)
        }
      }
    }

    // 设置 dom 可以拖拽
    this.dom.setAttribute('draggable', true)
    
    // 开始拖拽
    this.dom.ondragstart = null // 去掉以前加载的事件
    this.dom.ondragstart = (event: any) => {
      // event.dataTransfer.effectAllowed = 'move'
      dragInfo.state = 'pending'
      dragInfo.sourceId = colId
      dragInfo.targetLabel = event.target.outerText
      dragInfo.target = event.target
      dragInfo.sourceIndex = colOrder.findIndex(a => a === dragInfo.sourceId)
    }

    // 拖拽时经过
    this.dom.ondragover = null // 去掉以前加载的事件
    this.dom.ondragover = (event: any) => {
      event.preventDefault()
      clearTimeout(dragInfo.timeout)
      dragInfo.oldDom = event.target
      dragInfo.isLeft = event.offsetX < event.target.offsetWidth / 2

      // 判断左右，鼠标指针在容器的左面还是右面
      const borderStyle = (dragInfo.isLeft) ? 'none none none {}' : 'none {} none none'
      // 判断交换
      const borderStyle2 = 'ridge'

      // 判断是否同一个容器内拖拽
      if (dragInfo.targetLabel === event.target.outerText) {
        // 同一个容器，判断对齐方式 ctrl
        if (event.ctrlKey) {
          // 标题对齐，判断左右
          event.target.style.border = "5px dashed #7FFF01"
          event.target.style.borderStyle = borderStyle.replace('{}','dashed')
        } else {
          // 内容对齐，判断左右
          event.target.style.border = "5px dotted #A52A2f"
          event.target.style.borderStyle =borderStyle.replace('{}','dotted')
        }
      } else {
        // 不是同一个容器，判断排序还是交换位置
        if (event.ctrlKey) {
          // 交换
          event.target.style.border = "1px double #eb982c"
          event.target.style.borderStyle = borderStyle2
          // 设置开始 dom 的 边框
          dragInfo.target.style.border = "1px double #eb982c"
          dragInfo.target.style.borderStyle = borderStyle2
        } else {
          // 调整排序
          event.target.style.border = "4px double #2140c9"
          event.target.style.borderStyle = borderStyle.replace(/\{\}/g,'groove')
          // 恢复开始 dom 的 边框
          dragInfo.target.style.border = ""
          dragInfo.target.style.borderStyle = ''
        }
      }
      // event.dataTransfer.dropEffect = 'link'
    }

    // 拖拽离开
    this.dom.ondragleave = null // 去掉以前加载的事件
    this.dom.ondragleave = (event: any) => {
      clearTimeout(dragInfo.timeout)
      dragInfo.oldDom.style.border = ""
      dragInfo.timeout = setTimeout(() => {
        if (dragInfo.state !== 'end') {
          this.removeDom() // 调用移除事件
        }
      }, 800)
    }

    // 结束拖拽
    this.dom.ondrop = null // 去掉以前加载的事件
    this.dom.ondrop = (event: any) => {
      // event.preventDefault()
      // event.target.style.opacity = "1";
      clearTimeout(dragInfo.timeout)
      dragInfo.oldDom.style.border = ""
      // event.dataTransfer.dropEffect = 'link'
      dragInfo.state = 'end'
      dragInfo.offsetX = event.offsetX
      dragInfo.isLeft = dragInfo.offsetX < event.target.offsetWidth / 2
      dragInfo.ctrl = event.ctrlKey
      dragInfo.targetId = colId // textToColumnId[event.target.innerText]
      dragInfo.targetIndex = colOrder.findIndex(a => a === dragInfo.targetId)
      if (dragInfo.sourceId === dragInfo.targetId) {
        this.align() // 在同一个dom里拖拽，调整对齐
      } else {
        this.order() // 拖拽到另一个 dom，排序
      }
    }
    
  }
}
